/***************************************************
 ** @Desc : This file for B2C转账，此功能不在开放，已放弃维护
 ** @Time : 2019.04.13 13:56 
 ** @Author : Joker
 ** @File : transfer
 ** @Last Modified by : Joker
 ** @Last Modified time: 2019.04.13 13:56
 ** @Software: GoLand
****************************************************/
package controllers

import (
	"encoding/json"
	"errors"
	"io/ioutil"
	"net/http"
	"net/url"
	"recharge/controllers/implement"
	"recharge/models"
	"recharge/sys"
	"recharge/utils"
	"recharge/utils/interface_config"
	"strings"
)

type Transfer struct {
	KeepSession
}

var transferMdl = models.TransferRecord{}
var transferImpl = implement.TransferImpl{}

// 展示B2C转账页面
// @router /transfer/show_transfer/ [get,post]
func (the *Transfer) ShowPay() {
	userName := the.GetSession("userName")
	if userName != nil {
		the.Data["userName"] = userName.(string)
	}
	right := the.GetSession("FilterRight")
	if right != nil {
		the.Data["right"] = right.(int)
	}

	the.TplName = "transfer.html"
}

// 商户B2C转账
// @router /transfer/do_transfer/?:params [post]
func (the *Transfer) DoTransfer() {
	userId := the.GetSession("userId").(int)

	money := strings.TrimSpace(the.GetString("_accountNo"))
	accountType := the.GetString("accountType")

	var msg = utils.FAILED_STRING

	msg, verify := transferImpl.VerificationTransferInfo(money)
	if verify {
		//选择可充值商户
		XFMerchant := merchantFactor.QueryOneMerchantForRecharge()

		record := models.TransferRecord{}
		record.UserId = userId
		record.MerchantNo = XFMerchant.MerchantNo

		record.SerialNumber = utils.XF + globalMethod.GetNowTimeV2() + globalMethod.RandomString(10)
		record.TrOrderId = utils.XF + globalMethod.GetNowTimeV2() + globalMethod.RandomString(8)
		record.TrAmount, _ = globalMethod.MoneyYuanToFloat(money)
		record.TrAccountType = accountType
		record.TrProductName = "B2C" + globalMethod.GetNowTimeV2() + globalMethod.RandomString(8)

		record.TrNoticeUrl = interface_config.XF_TRANSFER_NOTICE_URL + record.TrOrderId

		// 多通道代付
		if strings.Compare(utils.XF, XFMerchant.ChannelType) == 0 {
			//先锋
			result, err := b2cTransfer(record, XFMerchant.SecretKey)

			if err != nil {
				msg = err.Error()
			} else {
				nowTime := globalMethod.GetNowTime()
				record.CreateTime = nowTime
				record.EditTime = nowTime
				record.Status = utils.I

				transferMdl.InsertTransferRecord(record)

				msg = string(result)
			}
		}
	}

	the.Data["Together_Play"] = msg
	the.TplName = "jump.html"
}

// b2c转账查询
// @router /transfer/transfer_query/?:params [get]
func (the *Transfer) TransferQuery() {
	queryId := the.GetString(":params")

	record := transferMdl.SelectOneTransferRecord(queryId)
	merchant := merchantMdl.SelectOneMerchantByNo(record.MerchantNo)

	var msg = utils.FAILED_STRING
	var flag = utils.FAILED_FLAG

	//只查询处理中的订单
	if strings.Compare(utils.I, record.Status) == 0 {
		//b2c转账查询
		result, err := b2cTransferQuery(record, merchant.SecretKey)
		if err != nil {
			msg = err.Error()
		} else {

			resp := models.XFPayResponseBody{}
			err = json.Unmarshal(result, &resp)
			if err != nil {
				sys.LogError("response data format is error:", err)
				msg = "b2c转账查询响应数据格式错误"
			} else {

				if strings.Compare("00000", resp.ResCode) == 0 ||
					strings.Compare("00001", resp.ResCode) == 0 ||
					strings.Compare("00002", resp.ResCode) == 0 {

					nowTime := globalMethod.GetNowTime()
					record.EditTime = nowTime
					record.Status = resp.Status
					record.Remark = resp.ResMessage

					if strings.Compare(utils.S, resp.Status) == 0 {
						// 加款
						flag = userMdl.SelectOneUserAdditionNotFee(record.UserId, record.TrAmount, record)
						if flag > 0 {
							sys.LogInfo("b2c转账订单:", record.TrOrderId, "加款成功")
						} else {
							sys.LogInfo("b2c转账订单:", record.TrOrderId, "加款失败")
						}
					} else if strings.Compare(utils.F, resp.Status) == 0 {
						transferMdl.UpdateTransferRecord(record)
					}
				} else {
					msg = "b2c转账查询错误：" + resp.ResMessage
					record.EditTime = globalMethod.GetNowTime()
					record.Remark = resp.ResMessage
					transferMdl.UpdateTransferRecord(record)
				}
			}
		}
	} else {
		msg = "只查询处理中的订单！"
	}

	the.Data["json"] = globalMethod.JsonFormat(flag, "", msg, "")
	the.ServeJSON()
	the.StopRun()
}

// b2c转账查询
func b2cTransferQuery(record models.TransferRecord, key string) ([]byte, error) {
	// 请求参数
	reqParams := url.Values{}
	reqParams.Add("service", "REQ_ORDER_QUERY_BY_ID")
	reqParams.Add("secId", interface_config.SECID)
	reqParams.Add("version", interface_config.VERSION)
	sn := utils.XF + globalMethod.GetNowTimeV2() + globalMethod.RandomString(10)
	reqParams.Add("reqSn", sn)
	reqParams.Add("merchantId", record.MerchantNo)
	reqParams.Add("merchantNo", record.TrOrderId)

	// 生成签名
	respParams := map[string]string{}
	respParams["service"] = "REQ_ORDER_QUERY_BY_ID"
	respParams["secId"] = interface_config.SECID
	respParams["version"] = interface_config.VERSION
	respParams["reqSn"] = sn
	respParams["merchantId"] = record.MerchantNo
	respParams["merchantNo"] = record.TrOrderId
	params := globalMethod.ToStringByMap(respParams)

	signBytes, err := merchantImpl.XFGenerateSign(params, key)
	if err != nil {
		s := "b2c转账查询生成签名失败"
		sys.LogTrace(s, err)
		return nil, errors.New(s)
	}
	reqParams.Add("sign", string(signBytes))

	// 发送请求
	resp, err := http.PostForm(interface_config.XF_RECHANGE_URL, reqParams)
	if err != nil {
		s := "b2c转账查询请求失败"
		sys.LogTrace(s, err)
		return nil, errors.New(s)
	}

	// 处理响应
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		s := "b2c转账查询响应为空"
		sys.LogTrace(s, err)
		return nil, errors.New(s)
	}
	defer resp.Body.Close()

	bytes, err := AES.AesDecrypt(body, []byte(key))
	if err != nil {
		s := "b2c转账查询响应解密错误"
		sys.LogTrace(s, err)
		return nil, errors.New(s)
	}

	return bytes, err
}

// b2c转账
func b2cTransfer(record models.TransferRecord, key string) ([]byte, error) {
	// 请求参数
	reqParams := url.Values{}
	reqParams.Add("service", "TO_UCF_CASHIER")
	reqParams.Add("secId", interface_config.SECID)
	reqParams.Add("version", interface_config.VERSION)
	reqParams.Add("reqSn", record.SerialNumber)
	reqParams.Add("merchantId", record.MerchantNo)

	// 需要的加密参数
	dataParams := models.B2CTransferData{}
	dataParams.MerchantNo = record.TrOrderId
	dataParams.Source = "1"
	dataParams.ProductType = "W"

	fen, _ := globalMethod.MoneyYuanToFen(record.TrAmount)
	dataParams.Amount = fen

	dataParams.TransCur = "156"
	dataParams.AccountType = record.TrAccountType
	dataParams.ProductName = record.TrProductName
	dataParams.ReturnUrl = record.TrNoticeUrl
	dataParams.NoticeUrl = record.TrNoticeUrl

	terminalParams := models.TerminalParams{}
	terminalParams.MerEquipmentIp = globalMethod.RandIpAddr()
	ter, _ := json.Marshal(&terminalParams)
	dataParams.TerminalParams = string(ter)

	// 加密参数
	dataString, _ := json.Marshal(&dataParams)
	data, err := AES.AesEncrypt(string(dataString), key)
	if err != nil {
		return nil, err
	}

	reqParams.Add("data", data)

	// 生成签名
	respParams := map[string]string{}
	respParams["service"] = "TO_UCF_CASHIER"
	respParams["secId"] = interface_config.SECID
	respParams["version"] = interface_config.VERSION
	respParams["reqSn"] = record.SerialNumber
	respParams["merchantId"] = record.MerchantNo
	respParams["data"] = data
	params := globalMethod.ToStringByMap(respParams)

	signBytes, err := merchantImpl.XFGenerateSign(params, key)
	if err != nil {
		s := "b2c转账生成签名失败"
		sys.LogTrace(s, err)
		return nil, errors.New(s)
	}
	reqParams.Add("sign", string(signBytes))

	// 发送请求
	resp, err := http.PostForm(interface_config.XF_RECHANGE_URL, reqParams)
	if err != nil {
		s := "b2c转账请求失败"
		sys.LogTrace(s, err)
		return nil, errors.New(s)
	}

	// 处理响应
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		s := "b2c转账响应为空"
		sys.LogTrace(s, err)
		return nil, errors.New(s)
	}
	defer resp.Body.Close()

	//bytes, err := AES.AesDecrypt(body, []byte(key))
	//if err != nil {
	//	s := "b2c转账响应解密错误"
	//	sys.LogTrace(s, err)
	//	return nil, errors.New(s)
	//}

	return body, err
}
